package cn.edu.zut.soft.graduate.massageCenter.bo;

import cn.edu.zut.soft.basic.core.model.bo.CommonResult;
import cn.edu.zut.soft.basic.core.model.dao.Criteria;
import cn.edu.zut.soft.basic.core.model.dao.Example;
import cn.edu.zut.soft.graduate.base.bo.BasicBOImpl;
import cn.edu.zut.soft.graduate.base.dao.BasicDAO;
import cn.edu.zut.soft.graduate.core.model.Impl.Identity;
import cn.edu.zut.soft.graduate.core.model.Impl.Message;
import cn.edu.zut.soft.graduate.core.query.MassageQuery;
import cn.edu.zut.soft.graduate.core.vo.LoginVO;
import cn.edu.zut.soft.graduate.massageCenter.dao.MassageDAO;
import cn.edu.zut.soft.graduate.massageCenter.generator.Builder;
import cn.edu.zut.soft.graduate.massageCenter.op.MessageOP;
import cn.edu.zut.soft.graduate.massageCenter.pojo.SendMessage;
import cn.edu.zut.soft.graduate.userCenter.dao.IdentityDAO;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Transformer;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.util.*;

/**
 * Created by chuchuang on 16/11/13.
 */
@Service
public class MessageBOImpl extends BasicBOImpl<Message, MassageQuery> implements MessageBO {

    @Resource
    private MassageDAO<Message> massageDAO;

    @Autowired
    private IdentityDAO<Identity> identityDAO;

    @Autowired
    private MessageOP messageOp;

    @Override
    protected BasicDAO<Integer, Message> getDAO() {
        return massageDAO;
    }


    @Override
    public CommonResult<Message> save(Message message, String operator) {
        // TODO: 2016/11/14  
        Example example = new Example();
        example.createCriteria().andIn("id", Arrays.asList(message.getAddressor(), message.getRecipients())).andEqualTo(DEL,del);
        List<Identity> identityList = identityDAO.selectByExample(example);
        Assert.notEmpty(identityList,"用户不存在");
        return super.save(message, operator);
    }

    @Override
    protected List<Criteria> Query(MassageQuery massageQuery) {
        Criteria criteria = new Criteria();
        if (massageQuery.getId() != null && massageQuery.getId() > 0) {
            criteria.andEqualTo("id", massageQuery.getId());
        }
        if (massageQuery.getAddressor() != null && massageQuery.getAddressor() > 0) {
            criteria.andEqualTo("addressor", massageQuery.getAddressor());
        }
        if (massageQuery.getRecipients() != null && massageQuery.getRecipients() > 0) {
            criteria.andEqualTo("recipients", massageQuery.getRecipients());
        }
        if (StringUtils.isNotBlank(massageQuery.getType())) {
            criteria.andEqualTo("`type`", massageQuery.getType());
        }
        if (massageQuery.getRead() != null) {
            criteria.andGreaterThanOrEqualTo("`read`", massageQuery.getRead());
        }
        if (massageQuery.getDel() !=null){
            criteria.andEqualTo("del",massageQuery.getDel());
        }else {
            criteria.andEqualTo("del",0);
        }
        if (StringUtils.isNotBlank(massageQuery.getTitle())){
            criteria.andLike("title",massageQuery.getTitle()+"%");
        }
        if (StringUtils.isBlank(massageQuery.getOrderByClause())){
            massageQuery.setOrderByClause("create_time desc");
        }
        return Collections.singletonList(criteria);
    }

    @Override
    public Integer notRead(Integer id) {
        Example example = new Example();
        example.createCriteria().andEqualTo("recipients", id).andEqualTo("`read`", 0).andEqualTo("del", 0);
        return getDAO().countByExample(example);
    }

    @Override
    @Transactional
    public Message read(Integer id, String operator) {
        Message message = this.get(id);
        Assert.notNull(message, "信息不存在");
        message.setRead(message.getRead() + 1);
        message.setUpdateAuthor(operator);
        getDAO().updateByPrimaryKey(message);
        return message;
    }

    @Override
    @Transactional
    public SendMessage AssemblyAndSend(LoginVO loginVO, List<Integer> ids, Builder builder) {
        Assert.notNull(loginVO,"loginvo is null");
        Assert.notEmpty(ids,"ids is null");
        Assert.notNull(builder,"builder is null");
        SendMessage sendMessage = new SendMessage();
        Identity identity = identityDAO.selectByPrimaryKey(loginVO.getId());
        Assert.notNull(identity,"用户账号异常");
        sendMessage.setIdentity(identity);
        Example example = new Example();
        example.createCriteria().andIn("id",ids).andEqualTo("del",0);
        List<Identity> identityList = identityDAO.selectByExample(example);
        Assert.notEmpty(identityList,"发送用户为空{}");
        sendMessage.setIdentityList(identityList);
        //转出ids 组
        Set<Integer> emps = new HashSet<>(identityList.size());
        CollectionUtils.collect(identityList, new Transformer() {
            @Override
            public Object transform(Object o) {
                Identity ide = (Identity) o;
                return ide.getId();
            }
        },emps);
        //记录用户不存在
        for (Integer id : ids) {
            if (!emps.contains(id)){
                sendMessage.getErrorList().put(id,"id不存在");
            }
        }
        //生成消息并发送
        messageOp.sendMessage(sendMessage, builder);
        return sendMessage;
    }

}
